from typing import List

import PySide6
from PySide6 import QtWidgets
from PySide6.QtCore import QThreadPool, Slot
from PySide6.QtGui import QAction
from PySide6.QtWidgets import QMainWindow, QVBoxLayout, QWidget, QTabWidget
from vnpy.event import Event

from mquant.trader.object import AccountModelData
from mquant.ui.monitor import AccountMonitor, LogMonitor, PositionMonitor, TradeMonitor, OrderMonitor
from mquant.ui.widget import MRiskQDialog, AccountQDialog
from mquant.ui.worker import Worker
from mquant_sqlite.sqlite_database import SqliteDatabase


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_ui()
        self.init_thread()

    def init_thread(self):
        # 创建线程池
        self.thread_pool = QThreadPool()

        db = SqliteDatabase()
        accounts: List[AccountModelData] = db.load_account_data()
        db.quit()

        self.workers = []
        for account in accounts:
            # 创建独立的数据库连接对象
            worker_db = SqliteDatabase()
            worker = Worker(account, worker_db)

            worker.signals.account.connect(self.handle_account)
            worker.signals.log.connect(self.handle_log)
            worker.signals.position.connect(self.handle_position)
            worker.signals.trade.connect(self.handle_trade)
            worker.signals.order.connect(self.handle_order)
            self.thread_pool.start(worker)
            self.workers.append(worker)

    def init_ui(self):
        self.setWindowTitle("Mtrader 风控系统")
        # 初始化顶部菜单栏
        self.init_menu()
        self.account_monitor = AccountMonitor()
        self.log_monitor = LogMonitor()
        self.position_monitor = PositionMonitor()
        self.trade_monitor = TradeMonitor()
        self.order_monitor = OrderMonitor()

        vbox = QVBoxLayout()
        vbox.addWidget(self.account_monitor)

        tab = QTabWidget()
        tab.addTab(self.position_monitor, "仓位")
        tab.addTab(self.order_monitor, "委托")
        tab.addTab(self.trade_monitor, "交易")

        vbox.addWidget(tab)

        vbox.addWidget(self.log_monitor)

        widget = QWidget()
        widget.setLayout(vbox)
        self.setCentralWidget(widget)

    def init_menu(self) -> None:
        # 顶部菜单栏
        menubar = self.menuBar()

        account_action = QAction("账户配置", self)
        account_action.triggered.connect(self.open_account_dialog)
        menubar.addAction(account_action)

        rm_action = QAction("风控配置", self)
        rm_action.triggered.connect(self.open_rm_dialog)
        menubar.addAction(rm_action)

    def open_account_dialog(self) -> None:
        """ """
        dialog: AccountQDialog = AccountQDialog()
        dialog.exec()

    def open_rm_dialog(self) -> None:
        """ """
        dialog: MRiskQDialog = MRiskQDialog()
        dialog.exec()

    @Slot(Event)
    def handle_account(self, result):
        # 处理工作线程发送的结果信号
        self.account_monitor.process_event(result)

    @Slot(Event)
    def handle_log(self, result):
        self.log_monitor.process_event(result)

    @Slot(Event)
    def handle_position(self, result):
        self.position_monitor.process_event(result)

    @Slot(Event)
    def handle_trade(self, result):
        self.trade_monitor.process_event(result)

    @Slot(Event)
    def handle_order(self, result):
        self.order_monitor.process_event(result)

    def closeEvent(self, event: PySide6.QtGui.QCloseEvent) -> None:
        # 弹出信息框
        n = QtWidgets.QMessageBox.question(
            self,
            "关闭确认",
            "是否确认关闭交易系统",
            QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No,
            QtWidgets.QMessageBox.StandardButton.No
        )

        # 判断选择结果
        if n != QtWidgets.QMessageBox.StandardButton.Yes:
            event.ignore()
            return

        # 关闭核心引擎
        self.thread_pool.waitForDone()
        for worker in self.workers:
            worker.quit()
        self.thread_pool.clear()

        # 接受关闭事件
        event.accept()
